package com.hanlyjiang.library.widget;

import java.util.ArrayList;
import java.util.List;


import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.DashPathEffect;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PathEffect;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;

import com.hanlyjiang.library.widget.paint.DPathShape;
import com.hanlyjiang.library.widget.paint.DShape;
import com.hanlyjiang.library.widget.paint.DTextShape;

/**
 * 手写涂鸦板View
 *
 * @author hanlyjiang
 * @version 1.0
 */
public class PainterView extends View {

    private Path mPath;
    private List<DShape> mListShape, mBackListShape;
    private List<List<float[]>> mMulitPoints, mBackMulitPoints;
    private List<float[]> mCurrPoints;
    private Paint mPathPaint;
    private TextPaint mTextPaint;

    private float mPreX, mPreY;
    private static final float TOUCH_TOLERANCE = 4;
    private  int color = Color.GREEN;
    private int lineWidth = 10;
    /**
     * 文字画笔的文字大小，Unit:px
     */
    private float textSize = 60;
    private Bitmap bitmap;

    public PainterView(Context context) {
        super(context);

        initial();
    }

    public PainterView(Context context, AttributeSet attrs) {
        super(context, attrs);
        WindowManager wm = (WindowManager) getContext()
                .getSystemService(Context.WINDOW_SERVICE);

        int width = wm.getDefaultDisplay().getWidth();
        bitmap = Bitmap.createBitmap(width,200,Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas();
        canvas.setBitmap(bitmap);
        initial();
    }

    private void initial() {
        mPathPaint = new Paint();
        // 设置绘制方式
        mPathPaint.setAntiAlias(true); // 抗锯齿状
        mPathPaint.setDither(true);
        mPathPaint.setColor(getColor());
        mPathPaint.setStrokeWidth(getLineWidth());
        mPathPaint.setStyle(Paint.Style.STROKE);
        mPathPaint.setStrokeJoin(Paint.Join.ROUND);
        mPathPaint.setStrokeCap(Paint.Cap.ROUND);

        mTextPaint = new TextPaint();
        mTextPaint.setAntiAlias(true);
        mTextPaint.setColor(getColor());
        mTextPaint.setTextSize(getTextSize());

        mListShape = new ArrayList<DShape>();
        mMulitPoints = new ArrayList<List<float[]>>();

        mBackListShape = new ArrayList<DShape>();
        mBackMulitPoints = new ArrayList<List<float[]>>();
    }


    public void clear() {
        mPath = null;
        mListShape.clear();
        mCurrPoints = null;
        mMulitPoints.clear();
        mBackListShape.clear();
        mBackMulitPoints.clear();
        invalidate();
    }


    @Override
    public void draw(Canvas canvas) {
        for (int i = 0; i < mListShape.size(); i++) {
            if (mListShape.get(i) instanceof DTextShape) {
                mListShape.get(i).draw(canvas, mTextPaint);
            } else if (mListShape.get(i) instanceof DPathShape) {
                mListShape.get(i).draw(canvas, mPathPaint);
            }
        }
        super.draw(canvas);
    }
    public Bitmap getPaintBitmap() {
//        return resizeImage(getDrawingCache(), 220, 50);
        destroyDrawingCache();//清除缓存才可以实时更新笔迹
        setDrawingCacheEnabled(true);
        if ( isDrawingCacheEnabled() ) {
           return getDrawingCache();
        }
        return null;
    }
    // 缩放
    public static Bitmap resizeImage(Bitmap bitmap, int width, int height) {
        //获取图片的宽高
        int originWidth = bitmap.getWidth();
        int originHeight = bitmap.getHeight();

        //这里缩放我们的尺寸，缩放多少自己去定义
        float scaleWidth = ((float) width) / originWidth;
        float scaleHeight = ((float) height) / originHeight;

        //进行缩放
        Matrix matrix = new Matrix();
        matrix.postScale(scaleWidth, scaleHeight);
        Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0, originWidth,
                originHeight, matrix, true);
        return resizedBitmap;
    }
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        //
        mPathPaint.setColor(getColor());
        mPathPaint.setStrokeWidth(getLineWidth());

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                touchDown(event);
                invalidate(); // 刷新ui界面
                break;
            case MotionEvent.ACTION_MOVE:
                touchMove(event);
                invalidate();
                break;
            case MotionEvent.ACTION_UP:
                touchUp(event);
                invalidate();
                break;
        }

        return true;
    }

    private boolean touchDown(MotionEvent event) {
        float x = event.getX();
        float y = event.getY();
        mPreX = x;
        mPreY = y;
        mPath = new Path();
        mPath.moveTo(x, y);
        mCurrPoints = new ArrayList<float[]>();
        mCurrPoints.add(new float[]{x, y});
        return true;
    }

    private boolean touchMove(MotionEvent event) {
        float x = event.getX();
        float y = event.getY();
        float dx = Math.abs(x - mPreX);
        float dy = Math.abs(y - mPreY);
        if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
            mPath.quadTo((mPreX + x) / 2f, (mPreY + y) / 2f, x, y);
            //线超过两点是添加
            if (mCurrPoints.size() == 1) {
                mMulitPoints.add(mCurrPoints);
                mListShape.add(new DPathShape(mPath, getColor(), getLineWidth()));
                //清除回退集合里的数据
                mBackListShape.clear();
                mBackMulitPoints.clear();
            }
            mCurrPoints.add(new float[]{x, y});
            mPreX = x;
            mPreY = y;
        }
        return true;
    }

    private boolean touchUp(MotionEvent event) {
        return true;
    }

    public void setEnabled(boolean value) {
        clear();
        invalidate();
        if (value) {
            setVisibility(View.VISIBLE);
        } else {
            setVisibility(View.GONE);
        }
        super.setEnabled(value);
    }

    /**
     * 撤销操作
     *
     * @return
     */
    public boolean undo() {
        int n = mListShape.size();
        if (n > 0) {
            //移除最后的操作过程。
            DShape pathShape = mListShape.remove(n - 1);
            List<float[]> points = mMulitPoints.remove(n - 1);
            mBackListShape.add(pathShape);
            mBackMulitPoints.add(points);
            invalidate();
            return true;
        }
        return false;
    }

    /**
     * 回退操作
     *
     * @return
     */
    public boolean redo() {
        int n = mBackListShape.size();
        if (n > 0) {
            // 移除最后的操作过程。
            DShape pathShape = mBackListShape.remove(n - 1);
            List<float[]> points = mBackMulitPoints.remove(n - 1);
            mListShape.add(pathShape);
            mMulitPoints.add(points);
            invalidate();
            return true;
        }
        return false;
    }

    public int getColor() {
        return color;
    }


    /**
     * 设置画笔颜色
     *
     * @param color
     */
    public  void setColor(int color) {
        this.color = color;
        mPathPaint.setColor(color);
        mTextPaint.setColor(color);
    }

    /**
     * 获取绘制的线的过程
     *
     * @return
     */
    public List<List<float[]>> getMulitLine() {
        return mMulitPoints;
    }
//画笔的宽度
    public int getLineWidth() {
        return lineWidth;
    }

    /**
     * 设置笔迹宽度
     *
     * @param lineWidth
     */
    public void setLineWidth(int lineWidth) {
        this.lineWidth = lineWidth;
    }

    public void setLineType(int type) {
        switch (type) {
//			case 0:
//				//空心
//				mPaint.setStyle(Paint.Style.STROKE);
//				break;
//			case 1:
//				//实心
//				mPaint.setStyle(Paint.Style.FILL);
//				break;
//			case 2:
//				//实心并且有边框
//				mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
//				break;
//			default:
//				mPaint.setStyle(Paint.Style.STROKE);
            case 0:
                PathEffect effect = new DashPathEffect(new float[]{1, 2, 4, 8}, 1);
                mPathPaint.setPathEffect(effect);
                break;
            case 1:
                mPathPaint.setPathEffect(null);
                break;
            default:
                mPathPaint.setPathEffect(null);
        }
    }


    /**
     * 绘制文字
     *
     * @param text 文字内容
     * @param x
     * @param y
     */
    public void drawText(String text, int x, int y) {
        mListShape.add(new DTextShape(text, x, y, getColor(), getTextSize()));
        mCurrPoints = new ArrayList<float[]>();
        mCurrPoints.add(new float[]{x, y});
        mMulitPoints.add(mCurrPoints);
        invalidate();
    }

    /**
     * 设置文本字体大小
     *
     * @param textSize
     */
    public void setTextSize(float textSize) {
        this.textSize = textSize;
        mTextPaint.setTextSize(textSize);
    }

    public float getTextSize() {
        return textSize;
    }

    /**
     * @return 一个和 pathPaint 具有相同属性的Paint
     */
    public Paint getPathPaint() {
        return new Paint(mPathPaint);
    }

    /**
     * @return 一个和 TextPaint 具有相同属性的Paint
     */
    public Paint getTextPaint() {
        return new Paint(mTextPaint);
    }

}
